"""
仓库管理命令
"""
import click
import subprocess
from repo_manager import RepoManager
from config import Config
from mrconfig_generator import MRConfigGenerator
from gitcode_client import GitCodeClient
from commands.cherry_pick import parse_pr_specs, fetch_pr_commits, fetch_pr_branch, cherry_pick_commits
from commands.upload import collect_pr_info, push_branch_to_fork
from i18n import t


@click.command()
@click.option('--branch', '-b', help='分支名（所有仓库使用同一分支）')
@click.option('--username', '-u', help='你的 GitCode 用户名（用于从你的 fork 仓拉取代码）')
@click.option('--repos', '-r', help='指定要操作的仓库（逗号分隔，如：cangjie_compiler,cangjie_runtime）或排除（加-号，如：-cangjie_docs）')
@click.option('--force', '-f', is_flag=True, help='重新初始化当前目录（可选删除已有仓库并重建配置）')
def init(branch, username, repos, force):
    """
    初始化项目配置（设置分支和用户名）
    
    只进行配置设置，不拉取代码。使用 `sync` 命令来拉取和更新代码。
    
    注意：
    - 分支和用户名会自动保存到项目配置（工作目录下的 .cjdev.yaml）
    - 后续的 `sync`、`add`、`upload` 等命令会自动使用这些配置
    - 使用 --repos 可以指定要操作的仓库或排除某些仓库
    - workspace 会设置为当前目录
    """
    import os
    from pathlib import Path
    
    # 获取当前目录作为 workspace
    current_dir = Path(os.getcwd()).resolve()
    
    # 创建 Config 实例，但强制使用当前目录作为 workspace
    config = Config()
    # 覆盖 workspace 为当前目录
    config.workspace = current_dir
    config.project_config_path = current_dir / ".cjdev.yaml"
    
    # 加载现有项目配置（如果存在）
    existing_project_config = {}
    if config.project_config_path.exists():
        existing_project_config = config._load_config_file(
            config.project_config_path,
            config.DEFAULT_PROJECT_CONFIG
        )
    
    # 获取全局配置的仓库列表（用于解析 --repos）
    global_config = config._load_config_file(config.global_config_path, config.DEFAULT_GLOBAL_CONFIG)
    all_repos = global_config.get("repos", [])
    default_repos = Config.DEFAULT_GLOBAL_CONFIG.get("repos", [])
    
    # 如果是 --force 模式且未提供 branch/username，则尝试从现有配置读取
    if force:
        if not branch:
            branch = existing_project_config.get("branch") or existing_project_config.get("base_branch") or config.get_default_branch()
        if not username:
            username = existing_project_config.get("gitcode_username")
    # 非 force 模式要求必须提供 branch 和 username
    if not branch or not username:
        click.echo(t("repo.init.missing_branch_username"), err=True)
        return
    
    # 解析仓库列表（如果指定了）
    repo_list = None
    if repos:
        repo_list = _parse_repos_option(repos, all_repos)
    elif force and existing_project_config.get("repos") is not None:
        repo_list = existing_project_config.get("repos")

    # 如果未显式传入或结果为空，兜底使用默认仓库集（10 个）/ fallback to default set
    if not repo_list:
        repo_list = (all_repos or default_repos).copy()
    
    # 保存分支、用户名、base分支和仓库列表到项目配置
    project_config = {"branch": branch, "gitcode_username": username, "base_branch": branch}
    if repo_list is not None:
        project_config["repos"] = repo_list
    
    config.save_project_config(**project_config)
    
    # 如果是强制模式，询问是否删除当前仓库目录
    if force:
        repo_manager = RepoManager(config)
        repo_names_to_check = repo_list if repo_list is not None else all_repos
        existing_paths = []
        for repo_name in repo_names_to_check:
            repo_path = repo_manager.get_repo_path(repo_name)
            if repo_path.exists():
                existing_paths.append(repo_path)
        if existing_paths:
            click.echo(t("repo.init.existing_dirs"))
            for path in existing_paths:
                click.echo(t("config.repo_item", repo=path))
            if click.confirm(t("repo.init.delete_prompt"), default=False):
                import shutil
                for path in existing_paths:
                    try:
                        shutil.rmtree(path)
                        click.echo(t("repo.init.delete_success", path=path))
                    except Exception as exc:
                        click.echo(t("repo.init.delete_failed", path=path, error=exc), err=True)
            else:
                click.echo(t("repo.init.keep_existing"))

    # 生成 .mrconfig 文件
    mr_gen = MRConfigGenerator(config)
    mr_gen.generate_mrconfig(username, branch, repo_list=repo_list, only_initialized=False)
    
    click.echo(t("repo.init.saved"))
    click.echo(t("repo.init.workspace", path=current_dir))
    click.echo(t("repo.init.branch_line", branch=branch))
    click.echo(t("repo.init.base_branch_line", branch=branch))
    click.echo(t("repo.init.username_line", username=username))
    if repo_list is not None:
        repo_names = ", ".join(repo_list)
        click.echo(t("repo.init.repos_custom", repos=repo_names, count=len(repo_list)))
    else:
        click.echo(t("repo.init.repos_all", count=len(all_repos)))
    
    click.echo(t("repo.init.sync_hint"))


@click.command()
@click.option('--force', '-f', is_flag=True, help='强制同步（从上游仓强制拉取，丢弃本地更改）')
@click.option('--repos', '-r', help='指定要操作的仓库（逗号分隔，如：cangjie_compiler,cangjie_runtime）或排除（加-号，如：-cangjie_docs）')
def sync(force, repos):
    """
    同步所有仓库（拉取和更新代码）
    
    对于未初始化的仓库：从你的 fork 仓克隆代码
    对于已初始化的仓库：从上游仓（Cangjie 主仓）的 base 分支（通常是 main）拉取最新代码并合并到当前分支
    
    同步基于 base 分支（PR 目标分支），而不是当前分支。这样可以确保当前分支始终包含 base 分支的最新更改。
    
    自动使用项目配置中的分支和用户名。
    注意：所有仓库需要保持同一分支。
    """
    config = Config()
    
    # 检查项目配置
    username = config.get_gitcode_username()
    branch = config.get_branch()
    
    if not username:
        click.echo(t("repo.common.username_missing"), err=True)
        click.echo(t("repo.common.username_hint"), err=True)
        return
    
    manager = RepoManager(config)
    
    # 解析仓库列表
    all_repos = config.get_repos()
    repo_list = _parse_repos_option(repos, all_repos)
    
    # 分离已初始化和未初始化的仓库
    initialized_repos = manager.get_initialized_repos()
    uninitialized_repos = [r for r in repo_list if r not in initialized_repos]
    
    # 克隆未初始化的仓库
    if uninitialized_repos:
        click.echo(t(
            "repo.sync.cloning_uninitialized",
            count=len(uninitialized_repos),
            branch=branch,
            username=username,
        ))
        manager.clone_all(branch, depth=1, username=username, repo_list=uninitialized_repos)
    
    # 同步已初始化的仓库（只同步在 repo_list 中的）
    repos_to_sync = [r for r in initialized_repos if r in repo_list]
    if repos_to_sync:
        action_key = "repo.sync.force_action" if force else "repo.sync.normal_action"
        action_label = t(action_key)
        click.echo(t("repo.sync.syncing", action=action_label, count=len(repos_to_sync)))
        manager.sync_all(force, repo_list=repos_to_sync)


@click.command()
@click.option('--repo', '-r', help='仓库名（不指定则显示所有已初始化仓库状态）')
def status(repo):
    """
    查看仓库状态
    
    默认只显示已初始化的仓库状态。
    未初始化的仓库不会显示（使用 'cjdev init' 初始化）。
    """
    config = Config()
    manager = RepoManager(config)
    
    # 显示 workspace 路径
    workspace = config.get_workspace()
    click.echo(t("repo.status.workspace", path=workspace))
    click.echo()
    
    if repo:
        # 检查是否已初始化
        if not manager.is_repo_initialized(repo):
            click.echo(t("repo.status.repo_not_initialized", repo=repo))
            return
        status_info = manager.status(repo)
        _print_status(status_info)
    else:
        statuses = manager.status_all()
        if not statuses:
            click.echo(t("repo.status.none_initialized"))
            click.echo(t("repo.status.init_hint"))
            return
        for status_info in statuses:
            _print_status(status_info)
            print()
        
        # 显示配置中但未初始化的仓库
        all_repos = config.get_repos()
        initialized_repos = manager.get_initialized_repos()
        uninitialized = [r for r in all_repos if r not in initialized_repos]
        if uninitialized:
            click.echo(t("repo.status.config_uninitialized", count=len(uninitialized)))
            for repo_name in uninitialized:
                click.echo(t("config.repo_item", repo=repo_name))
            click.echo(t("repo.status.config_uninitialized_hint"))


@click.command()
@click.argument('branch', required=True)
@click.option('--cherry-pick', '-c', help='Cherry-pick PR commits，格式: repo#pr_number (例如: cangjie_compiler#12)')
@click.option(
    '--upload',
    '-u',
    default=None,
    flag_value="",
    type=str,
    help='自动创建 PR 并设置目标分支（可选分支名，需要配合 --cherry-pick 使用）'
)
def start(branch, cherry_pick, upload):
    """
    创建新分支并切换到该分支
    
    在所有仓库中创建新分支并切换到该分支。如果分支已存在，会询问是否覆盖本地分支创建新分支还是切换到已有分支。
    
    如果指定了 --cherry-pick，会自动 cherry-pick 指定 PR 的 commits。
    支持多个仓库同时 cherry-pick，格式: repo1#pr_number,repo2#pr_number
    如果同时指定了 --upload，会在 cherry-pick 完成后自动创建 PR（PR 内容从源 PR 获取）。
    --upload 可以接受一个可选的分支名参数，用于设置 PR 的目标分支。
    
    注意：所有仓库需要保持同一分支。--upload 必须和 --cherry-pick 一起使用。
    
    \b
    示例:
        cjdev start feature-branch
        cjdev start feature-branch --cherry-pick cangjie_compiler#12
        cjdev start feature-branch -c cangjie_compiler#12 -u
        cjdev start feature-branch -c cangjie_compiler#12 -u main
        cjdev start feature-branch -c cangjie_compiler#12,cangjie_runtime#34 -u dev
    """
    config = Config()
    manager = RepoManager(config)
    
    # 处理 upload 参数：传入字符串，空字符串表示使用 --upload 未指定分支
    upload_enabled = upload is not None
    pr_base_branch = upload if upload else None
    
    # 验证 --upload 必须和 --cherry-pick 一起使用
    if upload_enabled and not cherry_pick:
        click.echo(t("repo.start.upload_requires_cherry_pick"), err=True)
        return
    
    # 检查分支是否在任何已初始化的仓库中存在
    if manager.branch_exists_in_any(branch):
        click.echo(t("repo.start.branch_exists", branch=branch))
        choice = click.prompt(t("repo.start.branch_exists_prompt"), type=str).strip()
        
        if choice == "1":
            # 覆盖本地分支，创建新分支
            click.echo(t("repo.start.overwriting", branch=branch))
            manager.checkout_all(branch, create=True, overwrite=True)
        elif choice == "2":
            # 切换到已有分支
            click.echo(t("repo.checkout.switching", branch=branch))
            manager.checkout_all(branch, create=False)
        else:
            click.echo(t("repo.start.invalid_choice"), err=True)
            return
    else:
        # 分支不存在，直接创建
        click.echo(t("repo.start.creating", branch=branch))
        manager.checkout_all(branch, create=True)
    
    # 更新项目配置中的分支
    config.save_project_config(branch=branch)
    
    # 更新 myrepos 配置文件中的分支信息
    mr_gen = MRConfigGenerator(config)
    mr_gen.update_mrconfig_branch(branch)
    
    # 如果指定了 --cherry-pick，执行 cherry-pick
    if cherry_pick:
        # 确定 PR 目标分支：如果 --upload 提供了分支名则使用它，否则使用配置中的 base_branch
        _auto_cherry_pick_and_upload(config, manager, branch, cherry_pick, upload_enabled, pr_base_branch)


@click.command()
@click.option('--branch', '-b', required=True, help='分支名（所有仓库使用同一分支）')
def checkout(branch):
    """
    切换到指定分支
    
    在所有仓库中切换到指定分支。分支必须已存在，如果不存在会报错。
    要创建新分支，请使用 'cjdev start <branch>' 命令。
    
    注意：所有仓库需要保持同一分支。
    
    \b
    示例:
        cjdev checkout -b main
        cjdev checkout -b dev
    """
    config = Config()
    manager = RepoManager(config)
    
    click.echo(t("repo.checkout.switching", branch=branch))
    manager.checkout_all(branch, create=False)
    
    # 更新项目配置中的分支
    config.save_project_config(branch=branch)
    
    # 更新 myrepos 配置文件中的分支信息
    mr_gen = MRConfigGenerator(config)
    mr_gen.update_mrconfig_branch(branch)


def _parse_repos_option(repos_str: str, all_repos: list) -> list:
    """
    解析 --repos 选项
    支持格式：
    - cangjie_compiler,cangjie_runtime (指定要操作的仓库)
    - -cangjie_docs (排除某个仓库)
    - cangjie_compiler,-cangjie_docs (混合使用)
    """
    if not repos_str:
        return all_repos
    
    # 分割逗号
    parts = [p.strip() for p in repos_str.split(',') if p.strip()]
    
    if not parts:
        return all_repos
    
    # 检查是否有排除项（以 - 开头）
    includes = [p for p in parts if not p.startswith('-')]
    excludes = [p[1:] for p in parts if p.startswith('-')]
    
    # 如果指定了包含项，从包含项开始
    if includes:
        result = includes
    else:
        # 如果没有包含项，从所有仓库开始
        result = all_repos.copy()
    
    # 排除指定的仓库
    result = [r for r in result if r not in excludes]
    
    return result


@click.command()
@click.argument('repos', required=True)
def add(repos):
    """
    添加仓库到配置并自动克隆
    
    可以添加一个或多个仓库（用逗号分隔）。添加后会自动克隆仓库。
    自动使用项目配置中的分支和用户名。
    
    示例:
        cjdev add new_repo
        cjdev add repo1,repo2,repo3
    """
    config = Config()
    repo_list = [r.strip() for r in repos.split(',') if r.strip()]
    
    if not repo_list:
        click.echo(t("repo.common.invalid_repos"), err=True)
        return
    
    # 添加仓库到配置
    added = config.add_repos(repo_list)
    if not added:
        click.echo(t("repo.add.all_exists"))
        return
    
    click.echo(t("repo.add.added_summary", count=len(added)))
    for repo in added:
        click.echo(t("config.repo_item", repo=repo))
    click.echo(t("repo.common.total_repos", count=len(config.get_repos())))
    
    # 获取用户名和分支（从项目配置）
    username = config.get_gitcode_username()
    if not username:
        click.echo()
        click.echo(t("repo.common.username_missing"), err=True)
        click.echo(t("repo.common.username_hint"), err=True)
        return
    
    branch = config.get_branch()
    click.echo(t("repo.add.branch_from_config", branch=branch))
    
    # 克隆新添加的仓库
    manager = RepoManager(config)
    click.echo()
    click.echo(t("repo.add.cloning_new", count=len(added), branch=branch, username=username))
    manager.clone_all(branch, depth=1, username=username, repo_list=added)
    
    # 更新 .mrconfig 文件
    mr_gen = MRConfigGenerator(config)
    mr_gen.generate_mrconfig(username, branch, repo_list=None, only_initialized=True)


@click.command()
@click.argument('repos', required=True)
@click.option('--keep-local', is_flag=True, help='保留本地仓库目录（只从配置中移除）')
def remove(repos, keep_local):
    """
    从配置中移除仓库并删除本地目录
    
    可以移除一个或多个仓库（用逗号分隔）。默认会删除本地仓库目录。
    
    示例:
        cjdev remove old_repo
        cjdev remove repo1,repo2,repo3
        cjdev remove old_repo --keep-local  # 只从配置移除，保留本地目录
    """
    config = Config()
    repo_list = [r.strip() for r in repos.split(',') if r.strip()]
    
    if not repo_list:
        click.echo(t("repo.common.invalid_repos"), err=True)
        return
    
    removed = config.remove_repos(repo_list)
    if removed:
        click.echo(t("repo.remove.removed_summary", count=len(removed)))
        for repo in removed:
            click.echo(t("config.repo_item", repo=repo))
        click.echo(t("repo.common.total_repos", count=len(config.get_repos())))
        
        # 删除本地仓库目录（除非指定保留）
        if not keep_local:
            manager = RepoManager(config)
            import shutil
            deleted_count = 0
            for repo in removed:
                repo_path = manager.get_repo_path(repo)
                if repo_path.exists():
                    try:
                        shutil.rmtree(repo_path)
                        click.echo(t("repo.remove.deleted_local", path=repo_path))
                        deleted_count += 1
                    except Exception as e:
                        click.echo(t("repo.remove.delete_failed", path=repo_path, error=e), err=True)
            
            if deleted_count > 0:
                click.echo(t("repo.remove.deleted_count", count=deleted_count))
            
            # 更新 .mrconfig 文件
            mr_gen = MRConfigGenerator(config)
            mr_gen.generate_mrconfig(
                config.get_gitcode_username(),
                None,  # 分支会在生成时从已初始化仓库获取
                repo_list=None,
                only_initialized=True
            )
        else:
            click.echo(t("repo.remove.keep_local"))
    else:
        click.echo(t("repo.remove.none_found"))


def _auto_cherry_pick_and_upload(config: Config, manager: RepoManager, branch: str, cherry_pick_spec: str, upload: bool, pr_base_branch: str = None):
    """
    自动 cherry-pick PR commits 并可选地创建 PR
    
    支持多个仓库同时 cherry-pick，格式: repo1#pr_number,repo2#pr_number
    
    :param config: 配置对象
    :param manager: 仓库管理器
    :param branch: 当前分支名
    :param cherry_pick_spec: PR 规格字符串，格式: repo#pr_number 或 repo1#pr_number,repo2#pr_number
    :param upload: 是否自动创建 PR
    :param pr_base_branch: PR 目标分支（如果为 None，则使用配置中的 base_branch）
    """
    client = GitCodeClient()
    owner = config.get_base_org()
    
    # 解析 PR 规格
    pr_specs = parse_pr_specs(cherry_pick_spec)
    if not pr_specs:
        click.echo(t("cherry.error_no_valid_pr_specifications_found"), err=True)
        return
    
    click.echo(t("repo.start.processing_multiple_prs", count=len(pr_specs)))
    
    # 存储每个仓库的处理结果
    results = {}
    
    # 遍历每个 PR 规格
    for repo, pr_number in pr_specs:
        click.echo("\n" + "="*70)
        click.echo(t("repo.start.processing_repo_pr", repo=repo, pr_number=pr_number))
        click.echo("="*70)
        
        # 检查仓库是否已初始化
        if not manager.is_repo_initialized(repo):
            click.echo(t("repo.start.repo_not_initialized", repo=repo), err=True)
            results[(repo, pr_number)] = {'success': False, 'error': 'Repository not initialized'}
            continue
        
        repo_path = manager.get_repo_path(repo)
        
        # 确保当前在正确的分支上
        current_branch_result = subprocess.run(
            ["git", "rev-parse", "--abbrev-ref", "HEAD"],
            cwd=repo_path,
            capture_output=True,
            text=True
        )
        if current_branch_result.returncode == 0:
            current_branch = current_branch_result.stdout.strip()
            if current_branch != branch:
                # 切换到目标分支
                switch_result = subprocess.run(
                    ["git", "checkout", branch],
                    cwd=repo_path,
                    capture_output=True,
                    text=True
                )
                if switch_result.returncode != 0:
                    click.echo(t("repo.start.failed_to_switch_branch", branch=branch), err=True)
                    results[(repo, pr_number)] = {'success': False, 'error': f'Failed to switch to branch {branch}'}
                    continue
        
        # 获取 PR 的 commits
        click.echo(t("repo.start.fetching_pr_commits", repo=repo, pr_number=pr_number))
        commits = fetch_pr_commits(client, owner, repo, pr_number)
        
        if not commits:
            click.echo(t("repo.start.no_commits_found"), err=True)
            results[(repo, pr_number)] = {'success': False, 'error': 'No commits found'}
            continue
        
        commit_shas = [commit.get('sha') for commit in commits if commit.get('sha')]
        if not commit_shas:
            click.echo(t("repo.start.no_valid_commits"), err=True)
            results[(repo, pr_number)] = {'success': False, 'error': 'No valid commits'}
            continue
        
        click.echo(t("repo.start.found_commits", count=len(commit_shas)))
        
        # 执行 cherry-pick
        click.echo(t("repo.start.cherry_picking"))
        success = cherry_pick_commits(repo_path, commit_shas)
        
        if not success:
            click.echo(t("repo.start.cherry_pick_failed"), err=True)
            results[(repo, pr_number)] = {'success': False, 'error': 'Cherry-pick failed'}
            continue
        
        click.echo(t("repo.start.cherry_pick_success"))
        results[(repo, pr_number)] = {'success': True}
        
        # 如果指定了 --upload，自动创建 PR
        if upload:
            _auto_create_pr_from_source(config, manager, repo, branch, owner, repo, pr_number, pr_base_branch)
    
    # 显示总结
    click.echo("\n" + "="*70)
    click.echo(t("repo.start.cherry_pick_summary"))
    click.echo("="*70)
    
    success_count = sum(1 for r in results.values() if r.get('success'))
    total_count = len(results)
    
    for (repo, pr_number), result in results.items():
        if result.get('success'):
            click.echo(t("repo.start.repo_pr_success", repo=repo, pr_number=pr_number))
        else:
            error = result.get('error', 'Unknown error')
            click.echo(t("repo.start.repo_pr_failed", repo=repo, pr_number=pr_number, error=error), err=True)
    
    click.echo(t("repo.start.total_success", success=success_count, total=total_count))
    click.echo("="*70)
    
    if not upload:
        click.echo(t("repo.start.cherry_pick_complete_no_upload"))


def _auto_create_pr_from_source(config: Config, manager: RepoManager, target_repo: str, branch: str, 
                                source_owner: str, source_repo: str, source_pr_number: int, pr_base_branch: str = None):
    """
    从源 PR 获取信息并自动创建 PR
    
    :param config: 配置对象
    :param manager: 仓库管理器
    :param target_repo: 目标仓库名（要创建 PR 的仓库）
    :param branch: 分支名
    :param source_owner: 源 PR 的所有者
    :param source_repo: 源 PR 的仓库名
    :param source_pr_number: 源 PR 编号
    :param pr_base_branch: PR 目标分支（如果为 None，则使用配置中的 base_branch）
    """
    client = GitCodeClient()
    owner = config.get_base_org()
    
    # 获取源 PR 信息
    click.echo(t("repo.start.fetching_source_pr", repo=source_repo, pr_number=source_pr_number))
    success, pr_info = client.get_pr(source_owner, source_repo, source_pr_number)
    
    if not success:
        error_msg = pr_info.get('error', 'Unknown error')
        click.echo(t("repo.start.failed_to_fetch_pr", error=error_msg), err=True)
        return
    
    # 从 PR 信息中提取 title 和 body
    # 根据用户要求，使用 string 和 body 字段
    pr_title = pr_info.get('title') or f"Cherry-pick from {source_repo}#{source_pr_number}"
    pr_body = pr_info.get('body') or ""
    
    # 如果 body 为空，添加源 PR 的链接
    if not pr_body.strip():
        pr_body = f"Cherry-picked from: https://gitcode.com/{source_owner}/{source_repo}/pulls/{source_pr_number}"
    else:
        # 在 body 开头添加源 PR 链接
        pr_body = f"Cherry-picked from: https://gitcode.com/{source_owner}/{source_repo}/pulls/{source_pr_number}\n\n{pr_body}"
    
    # 获取 PR 信息（head, base 等）
    repo_path = manager.get_repo_path(target_repo)
    if not repo_path.exists():
        click.echo(t("repo.start.repo_not_initialized", repo=target_repo), err=True)
        return
    
    # 获取用户名
    username = config.get_gitcode_username()
    if not username:
        # 尝试从 remote 获取
        remote_result = subprocess.run(
            ["git", "remote", "get-url", "origin"],
            cwd=repo_path,
            capture_output=True,
            text=True
        )
        if remote_result.returncode == 0:
            remote_url = remote_result.stdout.strip()
            if 'gitcode.com' in remote_url:
                parts = remote_url.replace('.git', '').rstrip('/').split('/')
                try:
                    gitcode_idx = [i for i, p in enumerate(parts) if 'gitcode.com' in p][0]
                    if len(parts) > gitcode_idx + 1:
                        potential_username = parts[gitcode_idx + 1]
                        if potential_username.lower() != config.get_base_org().lower():
                            username = potential_username
                except (IndexError, ValueError):
                    pass
    
    if not username:
        click.echo(t("repo.start.cannot_determine_username"), err=True)
        return
    
    head = f"{username}:{branch}"
    base = pr_base_branch if pr_base_branch else config.get_base_branch()
    
    # 推送分支到 fork
    click.echo(t("repo.start.pushing_branch", branch=branch, repo=target_repo))
    push_ok, push_error = push_branch_to_fork(target_repo, manager, config, branch)
    
    if not push_ok:
        click.echo(t("repo.start.failed_to_push_branch", error=push_error), err=True)
        click.echo(t("upload.continuing_anyway"))
        # 即使推送失败也继续尝试创建 PR（可能远程分支已存在）
    
    if not push_ok:
        click.echo(t("repo.start.failed_to_push_branch", error=push_error), err=True)
        return
    
    # 创建 PR
    click.echo(t("repo.start.creating_pr", repo=target_repo))
    ok, result = client.create_pr(owner, target_repo, pr_title, head, base, pr_body, None, None)
    
    if ok:
        pr_number = result.get('number') or result.get('iid')
        pr_url = result.get('web_url') or result.get('html_url') or result.get('url', '')
        click.echo(t("repo.start.pr_created", number=pr_number, url=pr_url))
    else:
        error_msg = result.get('error_message') or result.get('error') or str(result)
        click.echo(t("repo.start.failed_to_create_pr", error=error_msg), err=True)


def _print_status(status_info: dict):
    """打印状态信息"""
    if not status_info.get("exists"):
        click.echo(t("repo.status.repo_not_initialized", repo=status_info['repo']))
        return
    
    branch = status_info.get('branch')
    branch_value = branch or t("shared.unknown")
    last_commit = status_info.get('last_commit') or t("shared.unknown")
    click.echo(t("repo.status.repo_ready", repo=status_info['repo']))
    click.echo(t("repo.status.path_line", path=status_info['path']))
    click.echo(t("repo.status.branch_line", branch=branch_value))
    click.echo(t("repo.status.last_commit", commit=last_commit))
    
    if status_info.get('has_changes'):
        click.echo(t("repo.status.has_changes"))
    
    # 显示相对于 upstream 的领先和落后的提交数量
    ahead_count = status_info.get('ahead_count', 0)
    behind_count = status_info.get('behind_count', 0)
    base_branch = status_info.get('base_branch', 'base')
    upstream_repo_path = status_info.get('upstream_repo_path')
    
    # 如果 upstream_repo_path 存在，说明 upstream 检查成功，应该显示状态
    # 即使 ahead_count 和 behind_count 都是 0，也应该显示（表示完全同步）
    if upstream_repo_path is not None:
        status_parts = []
        if ahead_count > 0:
            status_parts.append(t("repo.status.ahead", count=ahead_count))
        if behind_count > 0:
            status_parts.append(t("repo.status.behind", count=behind_count))
        if not status_parts:
            status_parts.append(t("repo.status.in_sync"))
        status_text = ", ".join(status_parts)
        if upstream_repo_path:
            click.echo(t(
                "repo.status.upstream_line",
                source=upstream_repo_path,
                status=status_text,
                branch=base_branch,
            ))
        else:
            click.echo(t("repo.status.upstream_generic", status=status_text, branch=base_branch))
    
    # 显示相对于 origin 的领先和落后的提交数量
    origin_ahead_count = status_info.get('origin_ahead_count', 0)
    origin_behind_count = status_info.get('origin_behind_count', 0)
    branch = status_info.get('branch', 'unknown')
    origin_repo_path = status_info.get('origin_repo_path')
    
    if origin_ahead_count > 0 or origin_behind_count > 0:
        origin_status_parts = []
        if origin_ahead_count > 0:
            origin_status_parts.append(t("repo.status.ahead", count=origin_ahead_count))
        if origin_behind_count > 0:
            origin_status_parts.append(t("repo.status.behind", count=origin_behind_count))
        status_text = ", ".join(origin_status_parts)
        if origin_repo_path:
            click.echo(t(
                "repo.status.origin_line",
                source=origin_repo_path,
                status=status_text,
                branch=branch or t("shared.unknown"),
            ))
        else:
            click.echo(t(
                "repo.status.origin_generic",
                status=status_text,
                branch=branch or t("shared.unknown"),
            ))
    
    if status_info.get('is_behind'):
        click.echo(t("repo.status.behind_remote"))
    
    if 'error' in status_info:
        click.echo(t("repo.status.error_line", error=status_info['error']))

